package com.wzy.portfolio.utils;

import com.wzy.portfolio.model.MacdResult;
import com.wzy.portfolio.model.StockPriceDto;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class MacdUtil {

    /**
     * 计算EMA（指数加权移动平均）
     * @param prices
     * @param period
     * @return
     */
    private static List<Double> calculateEMAList(List<Double> prices, int period) {
        List<Double> emaList = new ArrayList<>();
        double sma = 0.0;
        // 前 period 天求 SMA 初始化
        for (int i = 0; i < period; i++) { sma += prices.get(i); }
        sma /= period;
        for (int i = 0; i < prices.size(); i++) {
            if (i < period - 1) {
                emaList.add(0.0); // 没法计算
            } else if (i == period - 1) {
                emaList.add(sma); // 初始化 EMA
            } else {
                double prevEma = emaList.get(i - 1);
                double ema = (prices.get(i) - prevEma) * (2.0 / (period + 1)) + prevEma;
                emaList.add(ema);
            }
        }
        return emaList;
    }

    /**
     * 计算MACD值
     * @param stockPrices
     * @param shortPeriod
     * @param longPeriod
     * @param signalPeriod
     * @return
     */
    public static List<MacdResult> calculateMACD(List<StockPriceDto> stockPrices, int shortPeriod, int longPeriod, int signalPeriod) {
        List<StockPriceDto> sortedPrices = stockPrices.stream() .sorted(Comparator.comparing(StockPriceDto::getPriceTime)) .collect(Collectors.toList());
        List<Double> prices = sortedPrices.stream() .map(StockPriceDto::getCurrentPrice) .collect(Collectors.toList());

        // 分别计算 short 和 long EMA 全列表
        List<Double> shortEmaList = calculateEMAList(prices, shortPeriod);
        List<Double> longEmaList = calculateEMAList(prices, longPeriod);

        List<Double> difList = new ArrayList<>();
        for (int i = 0; i < prices.size(); i++) {
            double shortEma = shortEmaList.get(i);
            double longEma = longEmaList.get(i);
            difList.add(shortEma - longEma);
        }

        // 计算 DEA 列表
        List<Double> deaList = calculateEMAList(difList, signalPeriod);

        // 生成最终的 MACD 结果，确保不越界
        List<MacdResult> macdResults = new ArrayList<>();
        for (int i = 0; i < deaList.size(); i++) {
            double dif = difList.get(i);
            double dea = deaList.get(i);
            double macd = 2 * (dif - dea);
            String date = sortedPrices.get(i).getPriceTime();
            macdResults.add(new MacdResult(date, dif, dea, macd));
        }
        return macdResults;
    }

}
